{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6dc90f3a-31d2-4959-964b-5e46cb5afc58",
   "metadata": {},
   "source": [
    "Chapter 03\n",
    "\n",
    "# 矩阵乘法第一视角\n",
    "《线性代数》 | 鸢尾花书：数学不难"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "638205aa-3e6b-4ae5-8e03-01db623f052b",
   "metadata": {},
   "source": [
    "这段代码主要涉及矩阵的基本运算，包括矩阵转置、矩阵乘法，以及通过循环逐元素计算矩阵乘积的方式。以下是详细的数学解析：\n",
    "\n",
    "### 1. 定义矩阵 $A$\n",
    "\n",
    "代码首先定义了一个 $2 \\times 3$ 矩阵 $A$：\n",
    "$$\n",
    "A = \\begin{bmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\end{bmatrix}\n",
    "$$\n",
    "其中，$A$ 具有 2 行 3 列。\n",
    "\n",
    "### 2. 计算 $A$ 的转置矩阵 $B$\n",
    "\n",
    "转置操作将矩阵的行和列进行交换，即：\n",
    "$$\n",
    "B = A^T = \\begin{bmatrix} 1 & 4 \\\\ 2 & 5 \\\\ 3 & 6 \\end{bmatrix}\n",
    "$$\n",
    "$B$ 是 $3 \\times 2$ 矩阵。\n",
    "\n",
    "### 3. 计算矩阵乘积 $C = A \\times B$\n",
    "\n",
    "矩阵 $C$ 由 $A$ 和 $B$ 进行矩阵乘法得到：\n",
    "$$\n",
    "C = A B\n",
    "$$\n",
    "根据矩阵乘法的定义，若 $A$ 为 $m \\times n$ 矩阵，$B$ 为 $n \\times p$ 矩阵，则矩阵乘法的结果是 $m \\times p$ 维矩阵，其元素计算公式如下：\n",
    "$$\n",
    "C_{ij} = \\sum_{k=1}^{n} A_{ik} B_{kj}\n",
    "$$\n",
    "具体计算：\n",
    "$$\n",
    "C = \\begin{bmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\end{bmatrix}\n",
    "    \\begin{bmatrix} 1 & 4 \\\\ 2 & 5 \\\\ 3 & 6 \\end{bmatrix}\n",
    "$$\n",
    "\n",
    "计算各个元素：\n",
    "$$\n",
    "C_{11} = 1 \\times 1 + 2 \\times 2 + 3 \\times 3 = 14\n",
    "$$\n",
    "$$\n",
    "C_{12} = 1 \\times 4 + 2 \\times 5 + 3 \\times 6 = 32\n",
    "$$\n",
    "$$\n",
    "C_{21} = 4 \\times 1 + 5 \\times 2 + 6 \\times 3 = 32\n",
    "$$\n",
    "$$\n",
    "C_{22} = 4 \\times 4 + 5 \\times 5 + 6 \\times 6 = 77\n",
    "$$\n",
    "\n",
    "最终得到：\n",
    "$$\n",
    "C = \\begin{bmatrix} 14 & 32 \\\\ 32 & 77 \\end{bmatrix}\n",
    "$$\n",
    "\n",
    "### 4. 计算 $C$ 的特定元素\n",
    "\n",
    "代码提取 $A$ 的第一行：\n",
    "$$\n",
    "A_{1,:} = \\begin{bmatrix} 1 & 2 & 3 \\end{bmatrix}\n",
    "$$\n",
    "提取 $B$ 的第一列：\n",
    "$$\n",
    "B_{:,1} = \\begin{bmatrix} 1 \\\\ 2 \\\\ 3 \\end{bmatrix}\n",
    "$$\n",
    "计算：\n",
    "$$\n",
    "A_{1,:} B_{:,1} = 1 \\times 1 + 2 \\times 2 + 3 \\times 3 = 14\n",
    "$$\n",
    "\n",
    "### 5. 逐元素计算 $C$\n",
    "\n",
    "代码通过两层循环遍历矩阵 $C$ 的每个元素，并使用矩阵乘法计算 $C_{ij}$：\n",
    "$$\n",
    "C_{ij} = A[i,:] \\times B[:,j]\n",
    "$$\n",
    "这一过程等价于矩阵乘法的定义，验证了 $C$ 的计算正确性。\n",
    "\n",
    "### 6. 计算 $D = B \\times A$\n",
    "\n",
    "接下来，代码计算 $B$ 和 $A$ 的矩阵乘法：\n",
    "$$\n",
    "D = B A\n",
    "$$\n",
    "\n",
    "$$\n",
    "D = \\begin{bmatrix} 1 & 4 \\\\ 2 & 5 \\\\ 3 & 6 \\end{bmatrix}\n",
    "    \\begin{bmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\end{bmatrix}\n",
    "$$\n",
    "\n",
    "计算每个元素：\n",
    "$$\n",
    "D_{11} = 1 \\times 1 + 4 \\times 4 = 17, \\quad\n",
    "D_{12} = 1 \\times 2 + 4 \\times 5 = 22, \\quad\n",
    "D_{13} = 1 \\times 3 + 4 \\times 6 = 27\n",
    "$$\n",
    "$$\n",
    "D_{21} = 2 \\times 1 + 5 \\times 4 = 22, \\quad\n",
    "D_{22} = 2 \\times 2 + 5 \\times 5 = 29, \\quad\n",
    "D_{23} = 2 \\times 3 + 5 \\times 6 = 36\n",
    "$$\n",
    "$$\n",
    "D_{31} = 3 \\times 1 + 6 \\times 4 = 27, \\quad\n",
    "D_{32} = 3 \\times 2 + 6 \\times 5 = 36, \\quad\n",
    "D_{33} = 3 \\times 3 + 6 \\times 6 = 45\n",
    "$$\n",
    "\n",
    "最终：\n",
    "$$\n",
    "D = \\begin{bmatrix} 17 & 22 & 27 \\\\ 22 & 29 & 36 \\\\ 27 & 36 & 45 \\end{bmatrix}\n",
    "$$\n",
    "\n",
    "### 7. 计算 $D$ 的特定元素\n",
    "\n",
    "代码提取 $B$ 的第一行：\n",
    "$$\n",
    "B_{1,:} = \\begin{bmatrix} 1 & 4 \\end{bmatrix}\n",
    "$$\n",
    "提取 $A$ 的第一列：\n",
    "$$\n",
    "A_{:,1} = \\begin{bmatrix} 1 \\\\ 4 \\end{bmatrix}\n",
    "$$\n",
    "计算：\n",
    "$$\n",
    "B_{1,:} A_{:,1} = 1 \\times 1 + 4 \\times 4 = 17\n",
    "$$\n",
    "\n",
    "### 8. 逐元素计算 $D$\n",
    "\n",
    "同理，通过两层循环遍历 $D$ 的每个元素：\n",
    "$$\n",
    "D_{ij} = B[i,:] \\times A[:,j]\n",
    "$$\n",
    "这再次验证了 $D$ 的正确性。\n",
    "\n",
    "### 总结\n",
    "\n",
    "- 代码展示了矩阵转置、矩阵乘法，以及如何手动计算矩阵乘法的每个元素。\n",
    "- 通过遍历计算 $C$ 和 $D$，代码验证了 NumPy 矩阵乘法的正确性。\n",
    "- 计算 $C$ 和 $D$ 的特定元素展示了矩阵乘法的计算原理。\n",
    "- 数学上，$A B$ 和 $B A$ 由于矩阵维度不同，结果维度和数值均不同，即：\n",
    "  $$\n",
    "  A B \\neq B A\n",
    "  $$\n",
    "  这表明矩阵乘法不是交换的（即 $A B \\neq B A$ 一般不成立）。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02710363-0bf1-42de-b81d-3c437d9dc998",
   "metadata": {},
   "source": [
    "## 初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "eb080991-466c-4ce3-a144-f6a1d0c7f20c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ebde45a1-1567-4965-af77-1035b6f7c869",
   "metadata": {},
   "source": [
    "## 定义矩阵 A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "7de1d2c2-a477-4f1a-82f9-1da2ec3d9aa6",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3],\n",
       "       [4, 5, 6]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = np.array([[1, 2, 3], \n",
    "              [4, 5, 6]])\n",
    "A"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "34b9b45f-170c-4864-ae8d-420957296f39",
   "metadata": {},
   "source": [
    "## 计算矩阵 B，即 A 的转置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "5f2bc3f1-14e8-4a19-87d9-e7589497b685",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 4],\n",
       "       [2, 5],\n",
       "       [3, 6]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "B = A.T\n",
    "B"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a59e677f-936a-4546-a27d-cabc6c2d1039",
   "metadata": {},
   "source": [
    "## 计算矩阵乘法 A @ B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "d86c564a-7c64-466d-9763-5080b67014c3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[14, 32],\n",
       "       [32, 77]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "C = A @ B\n",
    "C"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "60198f9f-686e-4951-875c-893a813f282e",
   "metadata": {},
   "source": [
    "## 计算 C 的第1行、第1列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "5e241bcc-48c4-499c-840d-4263605aea08",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3]])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A[[0],:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "bb6694cf-efd6-4431-a604-babd519bd5d7",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1],\n",
       "       [2],\n",
       "       [3]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "B[:,[0]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "18340bf4-1203-469b-aab1-84208309a4e0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[14]])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A[[0],:] @ B[:,[0]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c5bdb5d4-4085-4542-9c21-13d2375f769f",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "72183d3a-71b6-4b77-88cb-4b24bdfcc850",
   "metadata": {},
   "source": [
    "## 逐元素计算 C 的每个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "512a1c07-7596-4e2f-b959-bfab09872a62",
   "metadata": {},
   "outputs": [],
   "source": [
    "rows, cols = C.shape\n",
    "C_manual = np.zeros((rows, cols))  # 创建一个相同形状的零矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "f27a14a3-7e47-468c-bf15-dc290e1c26b9",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(rows):\n",
    "    for j in range(cols):\n",
    "        c_ij = A[[i],:] @ B[:,[j]]\n",
    "        c_ij = c_ij[0][0]\n",
    "        C_manual[i, j] = c_ij"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "0141358c-3fc1-4e52-bcf0-cd0d14038ea2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[14., 32.],\n",
       "       [32., 77.]])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "C_manual"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "40198ead-f8d4-4a89-bfe1-2900984ae73d",
   "metadata": {},
   "source": [
    "## 计算 B @ A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "b8939b70-2dda-4933-8111-8d57a92495da",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[17, 22, 27],\n",
       "       [22, 29, 36],\n",
       "       [27, 36, 45]])"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "D = B @ A\n",
    "D"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d03f38a-4c76-4491-a9d7-cd3b731a057f",
   "metadata": {},
   "source": [
    "## 计算 D 的第1行、第1列"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "f6a3832e-fa7c-4eaa-9c01-5120820c3fa4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 4]])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "B[[0],:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "672dd610-8e7e-4ab8-b7d0-aabd6d31ef7c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1],\n",
       "       [4]])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A[:,[0]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "9e7fa83e-12e0-4216-a514-c5b2dc685ac3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[17]])"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "B[[0],:] @ A[:,[0]]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e36e5730-4e27-4439-ad10-40e6ab31265e",
   "metadata": {},
   "source": [
    "## 逐元素计算 D 的每个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "2f69265f-7ba4-4826-880f-5f1dcbf81f7e",
   "metadata": {},
   "outputs": [],
   "source": [
    "rows, cols = D.shape\n",
    "D_manual = np.zeros((rows, cols))  # 创建一个相同形状的零矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "547d325b-9330-4e87-b7d9-ba5883623103",
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(rows):\n",
    "    for j in range(cols):\n",
    "        d_ij = B[[i],:] @ A[:,[j]]\n",
    "        d_ij = d_ij[0][0]\n",
    "        D_manual[i, j] = d_ij"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "2c10e809-9ca8-4c94-8302-c606a4b7834b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[17., 22., 27.],\n",
       "       [22., 29., 36.],\n",
       "       [27., 36., 45.]])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "D_manual"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fecf0a26-25d3-4d74-b126-937e844ff73d",
   "metadata": {},
   "source": [
    "作者\t**生姜DrGinger**  \n",
    "脚本\t**生姜DrGinger**  \n",
    "视频\t**崔崔CuiCui**  \n",
    "开源资源\t[**GitHub**](https://github.com/Visualize-ML)  \n",
    "平台\t[**油管**](https://www.youtube.com/@DrGinger_Jiang)\t\t\n",
    "\t\t[**iris小课堂**](https://space.bilibili.com/3546865719052873)\t\t\n",
    "\t\t[**生姜DrGinger**](https://space.bilibili.com/513194466)  "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
